`include "c3d_timescale.v"
`include "c3d_defines.v"

module c3d_block(
    x_start, y_start, x, y, z, w,
    start, busy, clk, rst
);

parameter WIDTH = `C3D_COORD_WIDTH;

parameter STEP_X = `C3D_RASTERIZE_STEP_X,
parameter STEP_Y = `C3D_RASTERIZE_STEP_Y;

input signed [WIDTH-1:0]    x_start;
input signed [WIDTH-1:0]    y_start;
input signed [WIDTH-1:0]    x[2:0];
input signed [WIDTH-1:0]    y[2:0];
input signed [WIDTH-1:0]    z[2:0];
input signed [WIDTH-1:0]    w[2:0];
input                       start;
output                      busy;
input                       clk;
input                       rst;

localparam STATE_IDLE = 1'b0,
           STATE_RUN = 1'b1;
reg state;

assign busy = (state != STATE_IDLE);

reg [63:0]      prog[255:0];
reg [7:0]       pc;
reg [7:0]       pc_end;

wire [63:0]     ins;
wire            mask[7:0][7:0];

assign ins = prog[pc];

genvar i, j;

// SIMT
generate
    for (i = 0; i < STEP_X; i = i + 1) begin : core_x
        for (j = 0; j < STEP_Y; j = j + 1) begin : core_y
            c3d_core core(
                .rst(rst),
                .clk(clk),
                .ins(ins),
                .xpos(x_start + i[15:0]), .ypos(y_start + j[15:0]),
                .x(x), .y(y),
                .busy(busy),
                .mask(mask[i][j])
            );
        end
    end
endgenerate

always @(posedge clk or negedge rst) begin
    if (!rst) begin
        state <= STATE_IDLE;
    end
    else begin
        case (state)
            STATE_IDLE: begin
                if (start) begin
                    pc <= 8'd0;
                    state <= STATE_RUN;
                    // 测试
                    pc_end <= 8'd3;
                    prog[0] <= 64'h000006C106C00101;
                    prog[1] <= 64'h000006C106C00002;
                    prog[2] <= 64'h000006C106C00103;
                    prog[3] <= 64'h0000000000000000;
                end
            end
            STATE_RUN: begin
                if (pc == pc_end) begin
                    state <= STATE_IDLE;
                end
                else begin
                    pc <= pc + 8'd1;
                end
            end
        endcase
    end
end

endmodule